<template>
  <div class="data-lineage">
    <el-card class="box-card">
      <template #header>
        <div class="card-header">
          <span>数据血缘关系图</span>
          <div class="operations">
            <el-select v-model="selectedObject" placeholder="选择数据对象" filterable>
              <el-option
                v-for="item in dataObjects"
                :key="item.id"
                :label="item.name"
                :value="item.id"
              />
            </el-select>
            <el-button type="primary" @click="searchLineage">查询</el-button>
          </div>
        </div>
      </template>
      
      <div class="lineage-container">
        <div class="control-panel">
          <el-radio-group v-model="direction" size="small">
            <el-radio-button label="both">上下游</el-radio-button>
            <el-radio-button label="upstream">上游</el-radio-button>
            <el-radio-button label="downstream">下游</el-radio-button>
          </el-radio-group>
          
          <el-slider v-model="depth" :min="1" :max="5" show-stops>
            <template #default="{ modelValue }">
              <div class="depth-label">深度: {{ modelValue }}</div>
            </template>
          </el-slider>
        </div>
        
        <div id="lineageGraph" class="lineage-graph"></div>
        
        <div class="lineage-legend">
          <div class="legend-item">
            <div class="legend-color" style="background-color: #6495ED;"></div>
            <span>数据表</span>
          </div>
          <div class="legend-item">
            <div class="legend-color" style="background-color: #9ACD32;"></div>
            <span>视图</span>
          </div>
          <div class="legend-item">
            <div class="legend-color" style="background-color: #FF7F50;"></div>
            <span>API</span>
          </div>
          <div class="legend-item">
            <div class="legend-color" style="background-color: #FFD700;"></div>
            <span>作业</span>
          </div>
        </div>
      </div>
      
      <el-empty v-if="!hasLineageData" description="请选择数据对象并点击查询按钮" />
    </el-card>
    
    <el-dialog v-model="lineageDetailVisible" title="数据流转明细" width="60%">
      <el-table :data="currentLineageDetails" style="width: 100%">
        <el-table-column prop="sourceField" label="源字段" />
        <el-table-column prop="targetField" label="目标字段" />
        <el-table-column prop="transformation" label="转换规则" />
      </el-table>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch } from 'vue'
import * as echarts from 'echarts'

// 数据对象列表
const dataObjects = ref([
  { id: '1', name: 'user_info (用户表)' },
  { id: '2', name: 'order_detail (订单表)' },
  { id: '3', name: 'product_catalog (产品表)' },
  { id: '4', name: 'user_behavior (用户行为表)' },
  { id: '5', name: 'daily_sales (销售表)' }
])

// 控制参数
const selectedObject = ref('')
const direction = ref('both')
const depth = ref(2)
const hasLineageData = ref(false)

// 血缘详情对话框
const lineageDetailVisible = ref(false)
const currentLineageDetails = ref([])

// 模拟血缘关系数据
const mockLineageData = {
  '1': {
    nodes: [
      { id: '1', name: 'user_info', category: 0, symbolSize: 50 },
      { id: '6', name: 'user_profile', category: 0, symbolSize: 40 },
      { id: '7', name: 'user_behavior_analysis', category: 1, symbolSize: 40 },
      { id: '8', name: 'marketing_segment', category: 1, symbolSize: 40 },
      { id: '9', name: 'user_api', category: 2, symbolSize: 40 },
      { id: '10', name: 'etl_user_daily', category: 3, symbolSize: 40 }
    ],
    links: [
      { source: '1', target: '6', value: '关联' },
      { source: '1', target: '7', value: '读取' },
      { source: '7', target: '8', value: '处理' },
      { source: '1', target: '9', value: '提供' },
      { source: '10', target: '1', value: '加载' }
    ],
    details: {
      '1-6': [
        { sourceField: 'id', targetField: 'user_id', transformation: '直接映射' },
        { sourceField: 'username', targetField: 'name', transformation: '直接映射' },
        { sourceField: 'email', targetField: 'contact_email', transformation: '直接映射' }
      ],
      '1-7': [
        { sourceField: 'id', targetField: 'user_id', transformation: '直接映射' },
        { sourceField: 'created_at', targetField: 'registration_date', transformation: '直接映射' }
      ]
    }
  },
  '2': {
    nodes: [
      { id: '2', name: 'order_detail', category: 0, symbolSize: 50 },
      { id: '1', name: 'user_info', category: 0, symbolSize: 40 },
      { id: '3', name: 'product_catalog', category: 0, symbolSize: 40 },
      { id: '11', name: 'order_summary', category: 1, symbolSize: 40 },
      { id: '12', name: 'financial_report', category: 1, symbolSize: 40 },
      { id: '13', name: 'etl_order_process', category: 3, symbolSize: 40 }
    ],
    links: [
      { source: '1', target: '2', value: '关联' },
      { source: '3', target: '2', value: '关联' },
      { source: '2', target: '11', value: '汇总' },
      { source: '11', target: '12', value: '计算' },
      { source: '13', target: '2', value: '处理' }
    ],
    details: {}
  }
}

// 监听选择的数据对象变化
watch([selectedObject, direction, depth], () => {
  if (hasLineageData.value) {
    renderLineageGraph()
  }
})

onMounted(() => {
  // 初始页面不显示血缘图
  hasLineageData.value = false
})

// 搜索血缘关系
const searchLineage = () => {
  if (!selectedObject.value) {
    return
  }
  
  // 模拟API请求
  setTimeout(() => {
    hasLineageData.value = true
    renderLineageGraph()
  }, 500)
}

// 渲染血缘关系图
const renderLineageGraph = () => {
  const chartDom = document.getElementById('lineageGraph')
  if (!chartDom) return
  
  const chart = echarts.init(chartDom)
  
  // 获取模拟数据
  const lineageData = mockLineageData[selectedObject.value] || mockLineageData['1']
  
  const option = {
    tooltip: {
      trigger: 'item',
      formatter: '{b}'
    },
    legend: [
      {
        data: ['数据表', '视图', 'API', '作业']
      }
    ],
    series: [
      {
        type: 'graph',
        layout: 'force',
        data: lineageData.nodes,
        links: lineageData.links,
        categories: [
          { name: '数据表' },
          { name: '视图' },
          { name: 'API' },
          { name: '作业' }
        ],
        roam: true,
        label: {
          show: true,
          position: 'right'
        },
        force: {
          repulsion: 100,
          gravity: 0.1,
          edgeLength: 150
        },
        edgeSymbol: ['circle', 'arrow'],
        edgeSymbolSize: [4, 8],
        edgeLabel: {
          show: true,
          formatter: '{c}',
          fontSize: 12
        },
        lineStyle: {
          opacity: 0.9,
          width: 2,
          curveness: 0
        }
      }
    ]
  }
  
  chart.setOption(option)
  
  // 点击事件处理
  chart.on('click', (params) => {
    if (params.dataType === 'edge') {
      const sourceId = params.data.source
      const targetId = params.data.target
      const detailKey = `${sourceId}-${targetId}`
      
      // 获取血缘详情数据
      if (lineageData.details && lineageData.details[detailKey]) {
        currentLineageDetails.value = lineageData.details[detailKey]
        lineageDetailVisible.value = true
      } else {
        // 模拟没有详情数据的情况
        currentLineageDetails.value = [
          { sourceField: '示例字段1', targetField: '示例字段A', transformation: '直接映射' },
          { sourceField: '示例字段2', targetField: '示例字段B', transformation: '拼接' }
        ]
        lineageDetailVisible.value = true
      }
    }
  })
}
</script>

<style scoped lang="scss">
.data-lineage {
  padding: 20px;
  
  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    
    .operations {
      display: flex;
      gap: 10px;
    }
  }
  
  .lineage-container {
    position: relative;
    
    .control-panel {
      margin-bottom: 20px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      
      .el-slider {
        width: 200px;
        margin-left: 20px;
      }
      
      .depth-label {
        font-size: 12px;
        color: #606266;
      }
    }
    
    .lineage-graph {
      height: 600px;
      border: 1px solid #e4e7ed;
      border-radius: 4px;
    }
    
    .lineage-legend {
      position: absolute;
      top: 50px;
      right: 20px;
      background: rgba(255, 255, 255, 0.8);
      padding: 10px;
      border-radius: 4px;
      border: 1px solid #e4e7ed;
      
      .legend-item {
        display: flex;
        align-items: center;
        margin-bottom: 5px;
        
        .legend-color {
          width: 16px;
          height: 16px;
          margin-right: 5px;
          border-radius: 2px;
        }
      }
    }
  }
}
</style> 